<script setup lang="ts">
import { ref, onMounted, reactive, computed, onBeforeUnmount } from 'vue'
import {
  Card as ACard,
  Row as ARow,
  Col as ACol,
  Statistic as AStatistic,
  Badge as ABadge,
  Alert as AAlert,
  Tabs as ATabs,
  TabPane as ATabPane,
  Spin as ASpin,
  Divider as ADivider,
  Empty as AEmpty,
} from 'ant-design-vue'
import {
  FileTextOutlined,
  AlertOutlined,
  TeamOutlined,
  BellOutlined,
  DeleteOutlined,
  CheckCircleOutlined,
  ClockCircleOutlined,
  UserOutlined,
} from '@ant-design/icons-vue'
import { useUserStore } from '@/stores/user'
import { getDashboardData } from '@/api/manger'
import * as echarts from 'echarts/core'
import { BarChart, LineChart, PieChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  DataZoomComponent,
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import * as THREE from 'three'
import ThreeDLogo from '@/components/ThreeDLogo.vue'

// 注册 ECharts 组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  DataZoomComponent,
  BarChart,
  LineChart,
  PieChart,
  CanvasRenderer,
])

const userStore = useUserStore()
const loading = ref(true)
const threeContainer = ref(null)

// Three.js 变量
let scene, camera, renderer, particles
let animationFrameId

// 仪表盘数据
const dashboardData = reactive({
  deletedPosts: 0,
  totalUsers: 0,
  publishedPosts: 0,
  pendingPosts: 0,
  activeUsers: {
    daily: 0,
    monthly: 0,
    weekly: 0,
    yearly: 0,
  },
  postsTimeline: {
    today: 0,
    week: 0,
    month: 0,
    year: 0,
  },
  reportsTimeline: {
    today: 0,
    week: 0,
    month: 0,
    year: 0,
  },
})

// 图表实例
const postsChartRef = ref(null)
const usersChartRef = ref(null)
const reportsChartRef = ref(null)
let postsChart = null
let usersChart = null
let reportsChart = null

// 获取仪表盘数据
const fetchDashboardData = async () => {
  try {
    loading.value = true
    const res = await getDashboardData()
    if (res.data.code === 200) {
      Object.assign(dashboardData, res.data.data)
    }
  } catch (error) {
    console.error('获取仪表盘数据失败:', error)
  } finally {
    loading.value = false
    // 数据加载完成后初始化图表
    initCharts()
  }
}

// 初始化 Three.js 场景
const initThreeScene = () => {
  if (!threeContainer.value) return

  // 创建场景
  scene = new THREE.Scene()

  // 创建相机
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.z = 30

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({
    alpha: true, // 透明背景
    antialias: true, // 抗锯齿
  })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.setPixelRatio(window.devicePixelRatio)

  // 确保DOM元素存在再进行appendChild操作
  if (threeContainer.value) {
    threeContainer.value.appendChild(renderer.domElement)
  } else {
    console.error('threeContainer DOM元素不存在')
    return // 如果DOM不存在则退出初始化
  }

  // 创建粒子系统
  const particlesGeometry = new THREE.BufferGeometry()
  const particlesCount = 1500

  const posArray = new Float32Array(particlesCount * 3)
  const colorsArray = new Float32Array(particlesCount * 3)

  // 设置粒子位置和颜色
  for (let i = 0; i < particlesCount * 3; i += 3) {
    // 位置
    posArray[i] = (Math.random() - 0.5) * 100
    posArray[i + 1] = (Math.random() - 0.5) * 100
    posArray[i + 2] = (Math.random() - 0.5) * 100

    // 颜色 - 使用蓝色调
    colorsArray[i] = Math.random() * 0.2 + 0.1 // R
    colorsArray[i + 1] = Math.random() * 0.5 + 0.3 // G
    colorsArray[i + 2] = Math.random() * 0.5 + 0.5 // B
  }

  particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3))
  particlesGeometry.setAttribute('color', new THREE.BufferAttribute(colorsArray, 3))

  // 粒子材质
  const particlesMaterial = new THREE.PointsMaterial({
    size: 0.2,
    vertexColors: true,
    transparent: true,
    opacity: 0.8,
  })

  // 创建粒子系统
  particles = new THREE.Points(particlesGeometry, particlesMaterial)
  scene.add(particles)

  // 添加窗口大小变化监听
  window.addEventListener('resize', onWindowResize)

  // 开始动画循环
  animate()
}

// 窗口大小变化处理
const onWindowResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}

// 动画循环
const animate = () => {
  animationFrameId = requestAnimationFrame(animate)

  // 旋转粒子系统
  particles.rotation.x += 0.0005
  particles.rotation.y += 0.0005

  // 渲染场景
  renderer.render(scene, camera)
}

// 初始化图表
const initCharts = () => {
  // 确保DOM已经渲染
  setTimeout(() => {
    initPostsChart()
    initUsersChart()
    initReportsChart()
  }, 100)
}

// 初始化帖子统计图表
const initPostsChart = () => {
  if (postsChartRef.value) {
    postsChart = echarts.init(postsChartRef.value)
    const option = {
      title: {
        text: '帖子统计',
        left: 'center',
      },
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)',
      },
      legend: {
        orient: 'vertical',
        left: 'left',
        data: ['已发布', '待审核', '已删除'],
      },
      series: [
        {
          name: '帖子数量',
          type: 'pie',
          radius: ['50%', '70%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2,
          },
          label: {
            show: false,
            position: 'center',
          },
          emphasis: {
            label: {
              show: true,
              fontSize: '18',
              fontWeight: 'bold',
            },
          },
          labelLine: {
            show: false,
          },
          data: [
            {
              value: dashboardData.publishedPosts,
              name: '已发布',
              itemStyle: { color: '#52c41a' },
            },
            { value: dashboardData.pendingPosts, name: '待审核', itemStyle: { color: '#faad14' } },
            { value: dashboardData.deletedPosts, name: '已删除', itemStyle: { color: '#ff4d4f' } },
          ],
        },
      ],
    }
    postsChart.setOption(option)
  }
}

// 初始化用户活跃度图表
const initUsersChart = () => {
  if (usersChartRef.value) {
    usersChart = echarts.init(usersChartRef.value)
    const option = {
      title: {
        text: '用户活跃度',
        left: 'center',
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        data: ['今日', '本周', '本月', '本年'],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          name: '活跃用户数',
          type: 'bar',
          data: [
            {
              value: dashboardData.activeUsers.daily,
              itemStyle: { color: '#1890ff' },
            },
            {
              value: dashboardData.activeUsers.weekly,
              itemStyle: { color: '#52c41a' },
            },
            {
              value: dashboardData.activeUsers.monthly,
              itemStyle: { color: '#faad14' },
            },
            {
              value: dashboardData.activeUsers.yearly,
              itemStyle: { color: '#ff4d4f' },
            },
          ],
        },
      ],
    }
    usersChart.setOption(option)
  }
}

// 初始化内容趋势图表
const initReportsChart = () => {
  if (reportsChartRef.value) {
    reportsChart = echarts.init(reportsChartRef.value)
    const option = {
      title: {
        text: '内容趋势',
        left: 'center',
      },
      tooltip: {
        trigger: 'axis',
      },
      legend: {
        data: ['帖子', '举报'],
        top: 30,
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['今日', '本周', '本月', '本年'],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          name: '帖子',
          type: 'line',
          stack: 'Total',
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: 'rgba(24, 144, 255, 0.5)',
              },
              {
                offset: 1,
                color: 'rgba(24, 144, 255, 0.1)',
              },
            ]),
          },
          emphasis: {
            focus: 'series',
          },
          data: [
            dashboardData.postsTimeline.today,
            dashboardData.postsTimeline.week,
            dashboardData.postsTimeline.month,
            dashboardData.postsTimeline.year,
          ],
        },
        {
          name: '举报',
          type: 'line',
          stack: 'Total',
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: 'rgba(255, 77, 79, 0.5)',
              },
              {
                offset: 1,
                color: 'rgba(255, 77, 79, 0.1)',
              },
            ]),
          },
          emphasis: {
            focus: 'series',
          },
          data: [
            dashboardData.reportsTimeline.today,
            dashboardData.reportsTimeline.week,
            dashboardData.reportsTimeline.month,
            dashboardData.reportsTimeline.year,
          ],
        },
      ],
    }
    reportsChart.setOption(option)
  }
}

// 获取问候语
const getGreeting = () => {
  const hour = new Date().getHours()
  if (hour < 6) return '凌晨好'
  if (hour < 9) return '早上好'
  if (hour < 12) return '上午好'
  if (hour < 14) return '中午好'
  if (hour < 17) return '下午好'
  if (hour < 19) return '傍晚好'
  return '晚上好'
}

// 格式化当前时间
const formattedTime = computed(() => {
  return new Date().toLocaleString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    weekday: 'long',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  })
})

// 窗口大小变化时重新初始化图表
const handleResize = () => {
  if (postsChart) postsChart.resize()
  if (usersChart) usersChart.resize()
  if (reportsChart) reportsChart.resize()
}

// 组件卸载前清理资源
onBeforeUnmount(() => {
  // 清理Three.js资源
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId)
  }

  if (renderer) {
    renderer.dispose()
  }

  if (particles && particles.geometry) {
    particles.geometry.dispose()
  }

  if (particles && particles.material) {
    particles.material.dispose()
  }

  // 移除事件监听器
  window.removeEventListener('resize', onWindowResize)

  // 清除场景引用
  scene = null
  camera = null
  renderer = null
  particles = null
})

// 确保在DOM挂载后再初始化Three.js
onMounted(() => {
  // 获取仪表盘数据
  fetchDashboardData()

  // 延迟初始化Three.js，确保DOM已经完全渲染
  setTimeout(() => {
    try {
      initThreeScene()
    } catch (error) {
      console.error('初始化ThreeJS场景失败:', error)
    }
  }, 200)
})
</script>

<template>
  <div class="welcome-page">
    <!-- Three.js 容器 -->
    <div ref="threeContainer" class="three-container"></div>

    <ASpin :spinning="loading" tip="加载中...">
      <div class="content-container">
        <!-- 欢迎卡片 -->
        <ACard class="welcome-card">
          <div class="welcome-header">
            <div class="welcome-info">
              <h1>{{ getGreeting() }}，{{ userStore.userInfo?.username || '管理员' }}</h1>
              <p>欢迎使用智能树岛后台管理系统</p>
              <div class="current-time">当前时间：{{ formattedTime }}</div>
            </div>
            <div class="welcome-logo">
              <img src="@/assets/logo.png" alt="Logo" />
            </div>
          </div>
        </ACard>

        <!-- 待处理提醒 -->
        <AAlert
          v-if="dashboardData.pendingPosts > 0"
          message="待处理提醒"
          :description="`有 ${dashboardData.pendingPosts} 条内容待审核，请及时处理！`"
          type="warning"
          show-icon
          class="alert-banner"
        />

        <!-- 数据统计卡片 -->
        <div class="statistics-grid">
          <ACard hoverable class="stat-card" :style="{ backgroundColor: '#e8f5e9' }">
            <AStatistic
              title="总用户数"
              :value="dashboardData.totalUsers"
              :valueStyle="{ color: '#1b5e20' }"
            >
              <template #prefix>
                <TeamOutlined />
              </template>
            </AStatistic>
          </ACard>

          <ACard hoverable class="stat-card" :style="{ backgroundColor: '#e8f5e9' }">
            <AStatistic
              title="已发布帖子"
              :value="dashboardData.publishedPosts"
              :valueStyle="{ color: '#2e7d32' }"
            >
              <template #prefix>
                <CheckCircleOutlined />
              </template>
            </AStatistic>
          </ACard>

          <ACard hoverable class="stat-card" :style="{ backgroundColor: '#e8f5e9' }">
            <AStatistic
              title="待审核帖子"
              :value="dashboardData.pendingPosts"
              :valueStyle="{ color: '#f9a825' }"
            >
              <template #prefix>
                <ClockCircleOutlined />
              </template>
            </AStatistic>
          </ACard>

          <ACard hoverable class="stat-card" :style="{ backgroundColor: '#e8f5e9' }">
            <AStatistic
              title="已删除帖子"
              :value="dashboardData.deletedPosts"
              :valueStyle="{ color: '#c62828' }"
            >
              <template #prefix>
                <DeleteOutlined />
              </template>
            </AStatistic>
          </ACard>
        </div>

        <!-- 图表区域 -->
        <div class="charts-container">
          <ACard class="chart-card" :style="{ backgroundColor: '#f1f8e9' }">
            <template #title>
              <FileTextOutlined /> 帖子统计
            </template>
            <div ref="postsChartRef" class="chart-container"></div>
          </ACard>

          <ACard class="chart-card" :style="{ backgroundColor: '#f1f8e9' }">
            <template #title>
              <UserOutlined /> 用户活跃度
            </template>
            <div ref="usersChartRef" class="chart-container"></div>
          </ACard>

          <ACard class="chart-card full-width" :style="{ backgroundColor: '#f1f8e9' }">
            <template #title>
              <BellOutlined /> 内容趋势
            </template>
            <div ref="reportsChartRef" class="chart-container trend-chart"></div>
          </ACard>
        </div>

        <!-- 3D 交互模块 -->
        <ACard class="three-d-card" :style="{ backgroundColor: '#e8f5e9' }">
          <template #title>
            <svg style="width:20px;height:20px;margin-right:8px" viewBox="0 0 24 24">
              <path fill="#2e7d32" d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z M16.2,16.2l-1.4,1.4L12,13.4l-2.8,4.2l-1.4-1.4l2.8-4.2L6,8.2l1.4-1.4l2.8,4.2l2.8-4.2L18,8.2L13.4,12L16.2,16.2z"/>
            </svg>
            3D 校园标志
          </template>
          <ThreeDLogo />
        </ACard>

        <!-- 校园标语 -->
        <div class="slogan">
          <h2>"听见每一片落叶声音"</h2>
          <p>智能树岛后台管理系统</p>
        </div>
      </div>
    </ASpin>
  </div>
</template>

<style scoped>
/* === 字体定义 === */
@font-face {
  font-family: 'YouYuan';
  src: local('Microsoft YaHei UI'), local('YouYuan');
}

@font-face {
  font-family: 'KaiTi';
  src: local('KaiTi');
}

/* === 全局样式 === */
.welcome-page {
  padding: 16px;
  position: relative;
  background: linear-gradient(to bottom, #f5fbf5, #e0f2e9);
  min-height: 100vh;
  font-family: "YouYuan", "KaiTi", "Microsoft YaHei", sans-serif;
}

.three-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
}

.content-container {
  max-width: 1400px;
  margin: 0 auto;
}

/* === 卡片样式 === */
.welcome-card,
.stat-card,
.chart-card,
.three-d-card {
  transition: all 0.3s ease;
  border-radius: 10px;
  box-shadow: 0 3px 6px rgba(0, 100, 0, 0.08);
  border: 1px solid rgba(120, 190, 120, 0.15);
  margin-bottom: 18px;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(4px);
}

.welcome-card:hover,
.stat-card:hover,
.chart-card:hover,
.three-d-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 5px 12px rgba(30, 130, 70, 0.15);
}

/* === 欢迎区域 === */
.welcome-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
}

.welcome-info h1 {
  font-family: "YouYuan", "KaiTi", sans-serif;
  font-size: 26px;
  margin-bottom: 6px;
  color: #1b5e20;
  font-weight: 600;
}

.welcome-info p {
  color: #2e7d32;
  margin-bottom: 5px;
  font-size: 16px;
}

.current-time {
  font-size: 14px;
  color: #43a047;
  margin-top: 6px;
  font-family: "Microsoft YaHei", sans-serif;
}

.welcome-logo img {
  height: 65px;
}

/* === 统计区域 === */
.statistics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
  margin-bottom: 18px;
}

.stat-card {
  padding: 16px;
  text-align: center;
}

.stat-card :deep(.ant-statistic-title) {
  color: #455a64;
  font-size: 15px;
  font-family: "KaiTi", "Microsoft YaHei", sans-serif;
}

.stat-card :deep(.ant-statistic-content) {
  font-size: 26px;
  font-weight: 600;
  font-family: 'Segoe UI', Tahoma, sans-serif;
}

/* === 图表区域 === */
.charts-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 18px;
  margin-bottom: 18px;
}

.chart-card.full-width {
  grid-column: 1 / -1;
}

.chart-card :deep(.ant-card-head) {
  border-bottom: 1px dashed #c8e6c9;
  padding: 12px 16px;
}

.chart-card :deep(.ant-card-head-title) {
  color: #1b5e20;
  font-family: "YouYuan", "KaiTi", sans-serif;
  font-size: 17px;
  display: flex;
  align-items: center;
}

.chart-container {
  height: 280px;
  width: 100%;
}

.trend-chart {
  height: 320px;
}

/* === 3D区域 === */
.three-d-card :deep(.ant-card-body) {
  padding: 16px;
  display: flex;
  justify-content: center;
}

/* === 标语区域 === */
.slogan {
  text-align: center;
  padding: 24px 0;
  margin: 24px 0;
  background: linear-gradient(to right, rgba(232, 245, 233, 0.8), rgba(220, 245, 225, 0.8));
  backdrop-filter: blur(4px);
  border-radius: 8px;
  border: 1px solid rgba(120, 190, 120, 0.2);
}

.slogan h2 {
  font-size: 32px;
  font-family: "YouYuan", "KaiTi", sans-serif;
  color: #1b5e20;
  margin-bottom: 16px;
  letter-spacing: 2px;
}

.slogan p {
  font-size: 17px;
  color: #388e3c;
  font-style: italic;
}

/* === 响应式调整 === */
@media (max-width: 768px) {
  .welcome-header {
    flex-direction: column;
    text-align: center;
  }

  .welcome-logo {
    margin-top: 16px;
  }

  .chart-container {
    height: 220px;
  }

  .statistics-grid {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 992px) {
  .charts-container {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style>